package com.oanda.blackberry.view;

import java.util.Vector;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.ListField;

import com.oanda.blackberry.restapi.Symbol;
import com.oanda.blackberry.util.DefaultController;
import com.oanda.blackberry.util.log.Logger;

public class SymbolsListField {
    private Symbol[] listData;
    private ListField listField;
    private ListCallBack listFieldCallBack = null;
    private DefaultController controller;

    public SymbolsListField(Symbol[] symbols, DefaultController controller) {
        Logger.log("created SymbolsListField");
        this.controller = controller;
        this.listFieldCallBack = new ListCallBack();

        this.listField = new ListField() {
            protected boolean keyChar(char key, int status, int time) {
                if ((key == '\n') || (key == ' ')) {
                    SymbolsListField.this.changeSelectedSymbol();
                    return true;
                }
                return super.keyChar(key, status, time);
            }

            protected boolean trackwheelClick(int status, int time) {
                SymbolsListField.this.changeSelectedSymbol();

                return true;
            }

            protected void drawFocus(Graphics graphics, boolean on) {
            }

            protected int moveFocus(int amount, int status, int time) {
                int ret = super.moveFocus(amount, status, time);
                invalidate();
                return ret;
            }

            protected void moveFocus(int x, int y, int status, int time) {
                int oldSelection = getSelectedIndex();
                super.moveFocus(x, y, status, time);
                int newSelection = getSelectedIndex();

                if (oldSelection != -1) {
                    invalidate(oldSelection);
                }

                if (newSelection != -1) {
                    invalidate(newSelection);
                } else {
                    setSelectedIndex(oldSelection);
                    invalidate(oldSelection);
                }
            }

            protected void onDisplay() {
                super.onDisplay();
            }

            protected void onUndisplay() {
                super.onUndisplay();
            }
        };
        this.listField.setEmptyString("No data!", 6);

        alphaSort(symbols);
        this.listData = symbols;
        this.listField.setRowHeight(70);

        this.listField.setCallback(this.listFieldCallBack);

        int elementLength = symbols.length;

        for (int count = 0; count < elementLength; count++)
            this.listField.insert(count);
    }

    private void sort(Symbol[] symbols) {
        Vector importantSelected = new Vector();
        Vector selected = new Vector();
        Vector importantNotSelected = new Vector();
        Vector notSelected = new Vector();
        Symbol symbol;
        for (int i = 0; i < symbols.length; i++) {
            symbol = symbols[i];
            if (symbol.isActive()) {
                if (Symbol.isPopularSymbol(symbol.getSymbol())) {
                    importantSelected.addElement(symbol);
                } else {
                    selected.addElement(symbol);
                }
            } else {
                if (Symbol.isPopularSymbol(symbol.getSymbol())) {
                    importantNotSelected.addElement(symbol);
                } else {
                    notSelected.addElement(symbol);
                }

            }

        }

        int index = 0;
        for (int i = 0; i < importantSelected.size(); i++) {
            symbols[index] = ((Symbol) importantSelected.elementAt(i));
            index++;
        }
        for (int i = 0; i < selected.size(); i++) {
            symbols[index] = ((Symbol) selected.elementAt(i));
            index++;
        }
        for (int i = 0; i < importantNotSelected.size(); i++) {
            symbols[index] = ((Symbol) importantNotSelected.elementAt(i));
            index++;
        }
        for (int i = 0; i < notSelected.size(); i++) {
            symbols[index] = ((Symbol) notSelected.elementAt(i));
            index++;
        }
    }

    public static void alphaSort(Symbol[] symbols) {
        Vector sorted = new Vector();

        sorted.addElement(symbols[0]);
        for (int i = 1; i < symbols.length; i++) {
            for (int j = 0; j < i; j++) {
                if (((Symbol) sorted.elementAt(j)).getSymbol().compareTo(symbols[i].getSymbol()) > 0) {
                    sorted.insertElementAt(symbols[i], j);
                    break;
                }
                if (j != i - 1)
                    continue;
                sorted.addElement(symbols[i]);
                break;
            }
        }

        for (int i = 0; i < symbols.length; i++) {
            symbols[i] = ((Symbol) sorted.elementAt(i));
        }
    }

    public ListField getList() {
        return this.listField;
    }

    private void changeSelectedSymbol() {
        if ((this.listField != null) && (this.listData != null)
                && (this.listField.getSelectedIndex() > -1)
                && (this.listField.getSelectedIndex() < this.listData.length)) {
            Symbol symbol = getSymbolSelected();
            if ((symbol != null) && (this.controller != null)) {
                boolean active = symbol.isActive();
                this.controller.useSymbol(symbol.getSymbol(), !active);
                symbol.setActive(!active);
                this.listField.invalidate(this.listField.getSelectedIndex());

                refreshList();
            }
        }
    }

    public Symbol getSymbolSelected() {
        int index = this.listField.getSelectedIndex();

        if ((index > -1) && ((this.listData[index] instanceof Symbol))) {
            return this.listData[index];
        }
        return null;
    }

    public Symbol[] getData() {
        return this.listData;
    }

    public String getSymbolName(int selected) {
        if ((selected > -1) && (selected < this.listData.length)) {
            return this.listData[selected].getSymbol();
        }
        return null;
    }

    private void refreshList() {
        this.listField.invalidate();
    }

    private class ListCallBack extends AbstractListFieldCallBack {
        private Bitmap selected = Bitmap.getBitmapResource("symbol-selected-29x29-p24.png");
        private Bitmap notSelected = Bitmap.getBitmapResource("symbol-notselected-29x29.png");

        public ListCallBack() {
            Bitmap bg = Bitmap.getBitmapResource("trades-row-480x70.png");
            Bitmap bgSelected = Bitmap.getBitmapResource("trades-row-selected-480x70.png");

            setBg(bg);
            setBgSelected(bgSelected);
        }

        public void drawListRow(ListField list, Graphics graphics, int index, int y, int w) {
            Logger.log("draw list row");

            int h = list.getRowHeight();
            int fontHeight = 28;

            Font font = DefaultController.getComponentFont().derive(0, fontHeight);

            drawBackground(graphics, 0, y, w, h,
                    SymbolsListField.this.listField.getSelectedIndex() == index);

            Object o = get(list, index);
            Symbol currentRow = null;

            if ((o != null) && ((o instanceof Symbol)))
                currentRow = (Symbol) get(list, index);
            else {
                return;
            }

            Bitmap icon = null;
            Font originalFont = graphics.getFont();
            int originalColor = graphics.getColor();
            int height = list.getRowHeight();

            if (currentRow != null) {
                if (currentRow.isActive())
                    icon = this.selected;
                else
                    icon = this.notSelected;
                if (icon != null) {
                    drawImage(graphics, 32, y, height, icon);
                }

                graphics.setColor(16119285);
                graphics.setFont(font.derive(0, fontHeight));
                graphics.drawText(currentRow.getSymbol(), 120, y + (h - 8 - fontHeight) / 2,
                        0x30 | 0x6);
            }
        }

        protected void drawBorder(Graphics graphics, int x, int y, int width, int height) {
            graphics.setColor(8421504);
            graphics.drawLine(x - 1, y, x + width - 1, y);
            graphics.drawLine(x - 1, y, x - 1, y + height - 1);
            graphics.drawLine(x + width, y - 1, x + width, y + height - 1);
            graphics.drawLine(x - 1, y + height - 1, x + width - 1, y + height - 1);
        }

        public Object get(ListField list, int index) {
            return SymbolsListField.this.listData[index];
        }
    }
}
